要调用在不同的平移单元中定义的内核内部函数时，这些函数需要用SYCL\_EXTERNAL标记。如果没有此属性，编译器将只编译用于设备代码外部的函数(从设备代码内部调用外部函数是非法的)。\par

如果在同一个转换单元中定义SYCL\_EXTERNAL函数，则有一些限制:\par

\begin{itemize}
	\item SYCL\_EXTERNAL只能用于函数。
	\item SYCL\_EXTERNAL函数不能使用原始指针作为形参或返回类型。必须使用显式指针类。
	\item SYCL\_EXTERNAL函数不能调用parallel\_for\_work\_item。
	\item SYCL\_EXTERNAL函数不能在parallel\_for\_work\_group范围内调用。
\end{itemize}

如果一个内核调用的函数不在同一个转译单元中，并且没有使用SYCL\_EXTERNAL声明，那么估计会出现如下错误\par

\begin{tcolorbox}[colback=white,colframe=black]
error: SYCL kernel cannot call an undefined function without SYCL\_EXTERNAL attribute
\end{tcolorbox}

如果函数本身在编译时没有SYCL\_EXTERNAL属性，则可以看到链接或运行时失败，例如\par

\begin{tcolorbox}[colback=white,colframe=black]
terminate called after throwing an instance of 'cl::sycl::compile\_program\_error' ...error: undefined reference to ...
\end{tcolorbox}

DPC++支持SYCL\_EXTERNAL。SYCL不需要编译器支持SYCL\_EXTERNAL，这是一个可选的特性。\par

\hspace*{\fill} \par %插入空行
\textbf{多重转译单元的性能影响}

编译模型的含义(见本章前面的部分)是，如果将设备代码分布到多个转译单元中，那么与设备代码位于同一位置时相比，可能会触发更多的即时编译。这是高度依赖于实现，并且会随着实现发生变化。\par

这种方式对性能的影响很小，在大多都可以忽略，但当进行微调以最大化代码性能时，可以考虑两件事来减轻影响:(1)将设备代码组合在同一个单元中，(2)使用提前编译来完全避免即时编译效应。由于这两种方法都需要一定的工作量，所以只有在完成开发，并试图从应用程序中榨出每一分性能时才会这样做。当使用这种调优时，有必要进行测试，以观察对SYCL实现的影响。\par











































